﻿using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace MyLib
{
	public class Room : Actor
	{
		private List<PlayerActor> players = new List<PlayerActor>();
		private int curTurn = 0;
		private bool isGameOver = false;

		private List<int> chessState = new List<int>();

		public Room()
		{
			InitChess();
		}
		//MakeMove 0
		public async Task MakeMove(int id, CGPlayerCmd cmd)
		{
			await _messageQueue;
			var pos = Convert.ToInt32(cmd.Cmd.Split(' ')[1]);
			chessState[pos] = id;

			curTurn++;
			var playerWho = curTurn % 2;
			var p = players[playerWho];


			var cmd2 = GCPlayerCmd.CreateBuilder();
			cmd2.Result = string.Format("MakeMove {0} {1}", id, pos);
			BroadcastToAll(cmd2);

			if (CheckWin())
			{
				GameOver();
			}
			else {
				var cmd3 = GCPlayerCmd.CreateBuilder();
				cmd3.Result = string.Format("NewTurn {0} {1}", curTurn, p.Id);
				BroadcastToAll(cmd3);
			}
		}

		private bool CheckWin()
		{
			return false;
		}


		private async Task GameOver()
		{
			if (!isGameOver)
			{
				isGameOver = true;
				var cmd = GCPlayerCmd.CreateBuilder();
				cmd.Result = "GameOver";
				BroadcastToAll(cmd);

				foreach (var p in players)
				{
					await p.SetRoom(null);
				}

				ActorManager.Instance.RemoveActor(Id);
			}
		}

		//中途离开房间
		public async Task Leave(int id)
		{
			await _messageQueue;
			await GameOver();
		}

		public async Task AddPlayer(int id1)
		{
			await _messageQueue;
			var player = ActorManager.Instance.GetActor(id1);
			//players.Add(id1, (PlayerActor)player);
			players.Add((PlayerActor)player);
			var p = (PlayerActor)player;
			//Room
			await p.SetRoom(this);
		}

		private void InitChess()
		{
			for (var i = 0; i < 9; i++)
			{
				chessState.Add(-1);
			}
			//0 1
		}

		public async Task GameStart()
		{
			await _messageQueue;
			curTurn = 0;

			var cmd = GCPlayerCmd.CreateBuilder();
			cmd.Result = "GameStart";
			BroadcastToAll(cmd);

			var cmd1 = GCPlayerCmd.CreateBuilder();
			cmd1.Result = string.Format("NewTurn {0} {1}", curTurn, players[0].Id);
			BroadcastToAll(cmd1);
		}

		private void BroadcastToAll(GCPlayerCmd.Builder cmd)
		{
			var parr = players;
			ServerBundle bundle;
			var bytes = ServerBundle.sendImmediateError(cmd, 0, 0, out bundle);
			ServerBundle.ReturnBundle(bundle);

			foreach (var p in parr)
			{
				p.GetAgent().SendBytes(bytes);
			}
		}
	}
}
